package com.tubeonfire.ajax.admin;

import java.io.IOException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.TreeMap;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.google.appengine.api.taskqueue.Queue;
import com.google.appengine.api.taskqueue.QueueFactory;
import com.google.appengine.api.taskqueue.TaskOptions;
import com.tubeonfire.entity.Channel;
import com.tubeonfire.entity.Playlist;
import com.tubeonfire.entity.SpecialTube;
import com.tubeonfire.entity.Tube;
import com.tubeonfire.model.admin.ChannelModel;
import com.tubeonfire.model.admin.PlaylistModel;
import com.tubeonfire.model.admin.SpecialTubeModel;
import com.tubeonfire.model.admin.TubeModel;
import com.tubeonfire.search.admin.TubeSearchEngine;
import com.tubeonfire.service.YoutubeService;
import com.tubeonfire.util.IdUniqueHelper;
import com.tubeonfire.util.TagHelper;
import com.tubeonfire.util.TubeValidate;

@SuppressWarnings("serial")
public class ProcessTube extends HttpServlet {

	private static final Logger log = Logger.getLogger(ProcessTube.class
			.getName());

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		HttpSession session = req.getSession();
		resp.setContentType("text/html; charset=UTF-8");
		resp.setCharacterEncoding("UTF-8");
		String url = "";
		try {
			String action = (String) req.getParameter("action");
			if (action != null && action.equals("add-to-category-from-youtube")) {
				String id = (String) req.getParameter("id");
				String playlistId = (String) req.getParameter("playlist");
				url = (String) req.getParameter("url");
				url = URLDecoder.decode(url, "UTF-8");

				Tube tube = YoutubeService.searchStaticById(id);
				Playlist pl = PlaylistModel.byId(playlistId, false);
				TreeMap recentAddTreeId = (TreeMap) session
						.getAttribute("recentAddTreeId");
				String currentPl = (String) session
						.getAttribute("currentPlaylist");
				if (currentPl != null && !currentPl.equals(pl.getId())) {
					recentAddTreeId = new TreeMap();
				} else if (recentAddTreeId == null) {
					recentAddTreeId = new TreeMap();
				}
				if (pl != null
						&& TubeValidate.checkForm(req, resp, session, action,
								tube)) {
					tube = processTubeDetail(playlistId, tube);
					// add author to site.
					Queue queue = QueueFactory.getDefaultQueue();
					queue.add(TaskOptions.Builder.withUrl(
							"/task-admin?action=add-author&uri="
									+ tube.getAuthorUrl()).method(
							TaskOptions.Method.GET));
					TubeModel.insert(tube);
					recentAddTreeId.put(tube.getId(), tube.getId());
					session.setAttribute("recentAddTreeId", recentAddTreeId);
					session.setAttribute("currentPlaylist", pl.getId());
					session.setAttribute("success",
							"Action success ! Video have been added to playlist \""
									+ pl.getTitle() + "\"");
				} else {
					log.warning("A2");
					session.setAttribute("error",
							"Action fails ! Please try again later !");

				}
				resp.getWriter().print(
						"<script type=\"text/javascript\"> window.location=\""
								+ url + "\";</script>");
			}
		} catch (Exception e) {
			log.warning(e.toString());
			e.printStackTrace();
			session.setAttribute("error",
					"Action fails ! Please try again later !");
			resp.getWriter().print(
					"<script type=\"text/javascript\"> window.location=\""
							+ url + "\";</script>");
		}
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		HttpSession session = request.getSession();
		try {
			String action = (String) request.getParameter("action");
			if (action != null && action.equals("add-all")) {
				if (!addAllVideosToCategory(session, request)) {
					response.getWriter().print("false");
				} else {
					response.getWriter().print("true");
				}
			} else if (action != null && action.equals("change-playlist")) {
				response.getWriter().print(
						changeAllVideosToCategory(session, request));
			} else if (action != null && action.equals("delete-all")) {
				response.getWriter().print(deleteAllVideos(session, request));
			} else if (action != null && action.equals("delete")) {
				response.getWriter().print(delete(session, request));
			} else if (action != null && action.equals("bump")) {
				bump(session, request);
			} else if (action != null && action.equals("set-slide")) {
				response.getWriter().print(setSlide(session, request));
			} else if (action != null && action.equals("remove-slide")) {
				response.getWriter().print(removeSlide(session, request));
			} else if (action != null && action.equals("remove-slideshow-all")) {
				response.getWriter().print(removeSlideAll(session, request));
			} else if (action != null && action.equals("slideshow-all")) {
				slideShowAll(session, request);
			} else if (action != null && action.equals("order-slide")) {
				orderSlide(session, request);
			} else if (action != null && action.equals("all-from-channel")) {
				response.getWriter().print(getAllFromChannel(session, request));
			}
		} catch (Exception e) {
			log.warning(e.toString());
			e.printStackTrace();
			session.setAttribute("error",
					"Action fails ! Please try again later !");
		}

	}

	private String getAllFromChannel(HttpSession session,
			HttpServletRequest request) {
		String channelId = (String) request.getParameter("channel");
		String playlistId = (String) request.getParameter("playlistId");
		String subcribe = (String) request.getParameter("subcribe");
		Playlist pl = PlaylistModel.byId(playlistId, false);
		if (channelId != null && channelId.length() > 0 && pl != null) {
			Queue queue = QueueFactory.getDefaultQueue();
			queue.add(TaskOptions.Builder.withUrl(
					"/task-admin?action=add-all-from-channel&channelId="
							+ channelId + "&playlistId=" + playlistId
							+ "&subcribe=" + subcribe).method(
					TaskOptions.Method.GET));
			return "";
		} else {
			return "Action fails ! Invalid channel !";
		}
	}

	private void orderSlide(HttpSession session, HttpServletRequest request) {
		String currentId = (String) request.getParameter("currentId");
		String prevId = (String) request.getParameter("prevId");
		String nextId = (String) request.getParameter("nextId");
		SpecialTube spTube = SpecialTubeModel.getByType("slide", false);
		List<String> listId = new ArrayList<String>();
		if (prevId == null) {
			listId.add(currentId);
			for (String string : spTube.getListTubeId()) {
				if (string.equals(currentId)) {
					continue;
				} else {
					listId.add(string);
				}
			}
		} else if (nextId == null) {
			for (String string : spTube.getListTubeId()) {
				if (string.equals(currentId)) {
					continue;
				} else {
					listId.add(string);
				}
			}
			listId.add(currentId);
		} else {
			for (String string : spTube.getListTubeId()) {
				if (string.equals(currentId)) {
					continue;
				}
				listId.add(string);
				if (string.equals(prevId)) {
					listId.add(currentId);
				}
			}
		}
		spTube.setListTubeId(listId);
		SpecialTubeModel.insert(spTube);

	}

	private String slideShowAll(HttpSession session, HttpServletRequest request) {
		try {
			String strIds = (String) request.getParameter("ids");
			String[] ids = strIds.split(",");
			SpecialTube spTube = SpecialTubeModel.getByType("slide", false);
			if (spTube == null) {
				spTube = new SpecialTube();
				spTube.setId(IdUniqueHelper.getId());
				spTube.setType("slide");
				SpecialTubeModel.insert(spTube);
			}
			List<String> listSlideTubeId = spTube.getListTubeId();
			for (int i = 0; i < ids.length; i++) {
				if (!ids[i].isEmpty()) {
					Tube tube = TubeModel.getById(ids[i], false);
					if (tube != null) {
						if (!listSlideTubeId.contains(tube.getId())) {
							if (listSlideTubeId.size() == 8) {
								listSlideTubeId.remove(0);
							}
							listSlideTubeId.add(tube.getId());
						} else {
							for (int j = 0; j < listSlideTubeId.size(); j++) {
								if (listSlideTubeId.get(j).equals(tube.getId())) {
									listSlideTubeId.remove(j);
									break;
								}
							}
							listSlideTubeId.add(tube.getId());
						}
					}
				}
			}
			spTube.setListTubeId(listSlideTubeId);
			SpecialTubeModel.insert(spTube);
			return "";
		} catch (Exception e) {
			return "Action fails ! Please try again !";
		}
	}

	private String removeSlideAll(HttpSession session,
			HttpServletRequest request) {
		try {
			String strIds = (String) request.getParameter("ids");
			String[] ids = strIds.split(",");
			SpecialTube spTube = SpecialTubeModel.getByType("slide", false);
			if (spTube == null) {
				spTube = new SpecialTube();
				spTube.setId(IdUniqueHelper.getId());
				spTube.setType("slide");
				SpecialTubeModel.insert(spTube);
			}
			List<String> listSlideTubeId = spTube.getListTubeId();
			for (int i = 0; i < ids.length; i++) {
				if (!ids[i].isEmpty()) {
					for (int j = 0; j < listSlideTubeId.size(); j++) {
						if (listSlideTubeId.get(j).equals(ids[i])) {
							listSlideTubeId.remove(j);
							break;
						}
					}
				}
			}
			spTube.setListTubeId(listSlideTubeId);
			SpecialTubeModel.insert(spTube);
			return "";
		} catch (Exception e) {
			return "Action fails ! Please try again !";
		}
	}

	private String setSlide(HttpSession session, HttpServletRequest request) {
		try {
			String strId = (String) request.getParameter("id");
			Tube tube = TubeModel.getById(strId, false);
			if (tube != null) {
				SpecialTube spTube = SpecialTubeModel.getByType("slide", false);
				if (spTube == null) {
					spTube = new SpecialTube();
					spTube.setId(IdUniqueHelper.getId());
					spTube.setType("slide");
					SpecialTubeModel.insert(spTube);
				}
				List<String> listSlideTubeId = spTube.getListTubeId();
				if (!listSlideTubeId.contains(tube.getId())) {
					if (listSlideTubeId.size() == 8) {
						listSlideTubeId.remove(0);
					}
					listSlideTubeId.add(tube.getId());
				} else {
					for (int j = 0; j < listSlideTubeId.size(); j++) {
						if (listSlideTubeId.get(j).equals(tube.getId())) {
							listSlideTubeId.remove(j);
							break;
						}
					}
					listSlideTubeId.add(tube.getId());
				}
				spTube.setListTubeId(listSlideTubeId);
				SpecialTubeModel.insert(spTube);
				return "";
			} else {
				return "Action fails ! Tube's not exits or have been deleted !";
			}
		} catch (Exception e) {
			return "Action fails ! Please try again !";
		}
	}

	private String removeSlide(HttpSession session, HttpServletRequest request) {
		try {
			String strId = (String) request.getParameter("id");
			if (strId != null && !strId.isEmpty()) {
				SpecialTube spTube = SpecialTubeModel.getByType("slide", false);
				if (spTube == null) {
					spTube = new SpecialTube();
					spTube.setId(IdUniqueHelper.getId());
					spTube.setType("slide");
					SpecialTubeModel.insert(spTube);
				}
				List<String> listSlideTubeId = spTube.getListTubeId();
				for (int j = 0; j < listSlideTubeId.size(); j++) {
					if (listSlideTubeId.get(j).equals(strId)) {
						listSlideTubeId.remove(j);
						break;
					}
				}
				spTube.setListTubeId(listSlideTubeId);
				SpecialTubeModel.insert(spTube);
				return "";
			} else {
				return "Action fails ! Tube's not exits or have been deleted !";
			}
		} catch (Exception e) {
			return "Action fails ! Please try again !";
		}
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private boolean addAllVideosToCategory(HttpSession session,
			HttpServletRequest request) {
		try {
			String strIds = (String) request.getParameter("ids");
			String plId = (String) request.getParameter("plId");
			Playlist pl = PlaylistModel.byId(plId, false);
			if (pl != null) {
				List<Tube> list = new ArrayList<Tube>();
				String[] ids = strIds.split(",");
				TreeMap recentAddTreeId = (TreeMap) session
						.getAttribute("recentAddTreeId");
				String currentPl = (String) session
						.getAttribute("currentPlaylist");
				if (currentPl != null && !currentPl.equals(plId)) {
					recentAddTreeId = new TreeMap();
				} else if (recentAddTreeId == null) {
					recentAddTreeId = new TreeMap();
				}
				Queue queue = QueueFactory.getDefaultQueue();
				for (int i = 0; i < ids.length; i++) {
					if (!ids[i].isEmpty()) {
						Tube tube = YoutubeService.searchStaticById(ids[i]);
						if (tube != null) {
							tube = processTubeDetail(plId, tube);
							recentAddTreeId.put(ids[i], ids[i]);
							list.add(tube);
							// add author to site.
							queue.add(TaskOptions.Builder.withUrl(
									"/task-admin?action=add-author&uri="
											+ tube.getAuthorUrl()).method(
									TaskOptions.Method.GET));
						}
					}
				}
				TubeModel.insert(list);
				session.setAttribute("recentAddTreeId", recentAddTreeId);
				session.setAttribute("currentPlaylist", pl.getId());
				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			System.out.println("!ok");
			log.warning(e.toString());
			e.printStackTrace();
			return false;
		}
	}

	private String changeAllVideosToCategory(HttpSession session,
			HttpServletRequest request) {
		try {
			String strIds = (String) request.getParameter("ids");
			String plId = (String) request.getParameter("plId");
			Playlist pl = PlaylistModel.byId(plId, false);
			if (pl != null) {
				List<Tube> list = new ArrayList<Tube>();
				String[] ids = strIds.split(",");
				for (int i = 0; i < ids.length; i++) {
					if (!ids[i].isEmpty()) {
						Tube tube = TubeModel.getById(ids[i], false);
						if (tube != null) {
							tube.setPlaylistId(plId);
							list.add(tube);
						}
					}
				}
				TubeModel.insert(list);
				return "";
			} else {
				return "Action fails ! Playlist's not exits or has been deleted !";
			}
		} catch (Exception e) {
			log.warning(e.toString());
			e.printStackTrace();
			return "Action fails ! Please try again !";
		}
	}

	private String deleteAllVideos(HttpSession session,
			HttpServletRequest request) {
		try {
			String strIds = (String) request.getParameter("ids");
			String[] ids = strIds.split(",");
			for (int i = 0; i < ids.length; i++) {
				if (!ids[i].isEmpty()) {
					Tube tube = TubeModel.getById(ids[i], false);
					if (tube != null) {
						TubeModel.delete(tube);
					} else {
						TubeSearchEngine.remove(ids[i]);
					}
				}
			}
			return "";
		} catch (Exception e) {
			return "Action fails ! Please try again !";
		}
	}

	private String delete(HttpSession session, HttpServletRequest request) {
		try {
			String strId = (String) request.getParameter("id");
			Tube tube = TubeModel.getById(strId, false);
			if (tube != null) {
				TubeModel.delete(tube);
				return "";
			} else {
				return "Action fails ! Tube's not exits or have been deleted !";
			}
		} catch (Exception e) {
			return "Action fails ! Please try again later !";
		}

	}

	private String bump(HttpSession session, HttpServletRequest request) {
		String strId = (String) request.getParameter("id");
		Tube tube = TubeModel.getById(strId, false);
		if (tube != null) {
			tube.setBumpPoint(Calendar.getInstance().getTimeInMillis() / 1000);
			TubeModel.insert(tube);
			return "";
		} else {
			return "Action fails ! Tube's not exits or have been deleted !";
		}
	}

	private Tube processTubeDetail(String plId, Tube tube) {
		tube.setPlaylistId(plId);
		if (tube.getTags().size() == 0) {
			tube.setTags(TagHelper.youTag(tube.getTitle() + " "
					+ tube.getDescription()));
		}
		tube.setOtherTags(TagHelper.getOtherTag(tube.getTags()));
		tube.setBumpPoint(Calendar.getInstance().getTimeInMillis() / 1000);
		if (ChannelModel.getById(tube.getChannelId()) == null) {
			Channel channel = new Channel();
			channel.setId(tube.getChannelId());
			channel.setTitle(tube.getChannelName());
			channel.setDescription(tube.getChannelName());
			channel.setDoc(Calendar.getInstance().getTime());
			channel.setUpdated(Calendar.getInstance().getTime());
			channel.setBumpPoint(Calendar.getInstance().getTimeInMillis() / 1000);
			channel.setStatus(1);
			ChannelModel.insert(channel);
		}
		return tube;
	}
}
